/*
    Meter JMX Utility Library
    Copyright (C) 2005  Noah Campbell

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
package info.noahcampbell.meter;


import java.util.HashMap;
import java.util.Map;

import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeDataSupport;
import javax.management.openmbean.CompositeType;
import javax.management.openmbean.OpenDataException;
import javax.management.openmbean.OpenType;
import javax.management.openmbean.SimpleType;

import org.apache.commons.math.stat.Frequency;

/**
 * @author Noah Campbell
 * @version 1.0
 */
public class CounterObserver extends MetricObserver<Counter, Frequency> implements Runnable {

    /**
     * @see MetricObserver#newInstance()
     */
    @Override
    protected Frequency newInstance() {
        return new Frequency();
    }

    /**
     * @param number 
     * @param obj 
     * @see MetricObserver#process(java.lang.Number, V)
     */
    @Override
    protected void process(Number number, Frequency obj) {
        obj.addValue(number.longValue());
    }

    /**
     * Construct a new <code>CounterObserver</code>.
     * @param counters 
     *
     */
    public CounterObserver(Counter...counters) {
       super(counters); 
    }
    
    public CompositeData getFrequencyData(Counter c) {
        return convert(this.getStats(c));
    }
    
    private CompositeData convert(Frequency f) {
        Map<String, Double> m = new HashMap<String, Double>(); 
        for(int i = 0; i < names.length; i++) {
            double total = f.getCumPct(Double.valueOf(Math.pow(2.0, 6+i)).longValue());
            m.put(names[i], total);
        }
        
        CompositeDataSupport cds = null;
        try {
            cds = new CompositeDataSupport(counterType, m);
        } catch (OpenDataException e) {
            // ignore
        }
        return cds;
    }
    
    private static CompositeType counterType = null;
    private static final String[] names = new String[] {"64b", "128b", "256b", "512b", "1k", "2k", "4k", "8k","inf"};
    static {
        
        String[] descs = new String[] {"64b", "128b", "256b", "512b", "1k", "2k", "4k", "8k","infinity"};
        OpenType[] types = new OpenType[] { SimpleType.DOUBLE,
                SimpleType.DOUBLE,
                SimpleType.DOUBLE,
                SimpleType.DOUBLE,
                SimpleType.DOUBLE,
                SimpleType.DOUBLE,
                SimpleType.DOUBLE,
                SimpleType.DOUBLE,
                SimpleType.DOUBLE
        };
        
        try {
            counterType = new CompositeType(Frequency.class.getName(), "frequency", names, descs, types);
        } catch (OpenDataException e) {
            // ignore for now.
            counterType = null;
        }
    }

}
